#pragma once
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <cerrno>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <functional>
#include <signal.h>
#include "logMessage.hpp"
using namespace std;
static const uint16_t gport = 8080;
static const int gbacklog = 5;
class tcp_Server;
class ThreadData
{
public:
    ThreadData(tcp_Server *server, int sock) : _this(server), _sock(sock)
    {}
    ~ThreadData()
    {}
public:
    tcp_Server *_this;
    int _sock;
};
class tcp_Server
{

public:
    tcp_Server(const uint16_t &port = gport) : _port(port)
    {
    }
    ~tcp_Server()
    {
    }
    
    static void *work(void *args)
    {
        ThreadData* tmp = (ThreadData *)(args);
        tmp->_this->ServerIO(tmp->_sock);
        close(tmp->_sock);
        delete tmp;
        tmp = nullptr;
    }
    void ServerIO(int sock)
    {
        char buffer[1024];
        while (1)
        {
            ssize_t n = read(sock, buffer, sizeof buffer);
            if (n < 0)
            {
                //logMessage(FATAL, "read error");
                cout<<"read error"<<endl;
                exit(2);
            }
            else if (n == 0)
            {
                cout << "Clent quit me too" << endl;
                break;
            }
            // 转发给客户端
            buffer[n] = 0;
            string message = "recv message :";
            message += buffer;
            cout << message << endl;
            int i = write(sock,buffer,strlen(buffer));
            if (i < 0)
            {
                //logMessage(FATAL, "Server write error");
                cout<<"server write error"<<endl;
                exit(2);
            }
        }
    }
    void Init()
    {
        // 创建套接字
        _socketfd = socket(AF_INET, SOCK_STREAM, 0);
        if (_socketfd < 0)
        {
            logMessage(ERROR, "socket create error errno : %d",errno);
            exit(2);
        }
        logMessage(NORMAL,"socket success");
        // bind
        struct sockaddr_in local;
        local.sin_family = AF_INET;
        local.sin_port = htons(_port);
        local.sin_addr.s_addr = INADDR_ANY;
        int n = bind(_socketfd, (struct sockaddr *)&local, sizeof(local));
        if (n < 0)
        {
            logMessage(ERROR, "bind error  errno : %d",errno);
            cerr << strerror(errno) << endl;
            exit(2);
        }
        logMessage(NORMAL, "bind success");
        // lisen
        _listenfd = listen(_socketfd, gbacklog);
        if (_listenfd < 0)
        {
            logMessage(ERROR, "listen error errno : %d",errno);
            exit(2);
        }
        logMessage(NORMAL, "listen success");
    }
    
    void start()
    {
        while (1)
        {
            // 建立新连接
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);
            int sock = accept(_socketfd, (struct sockaddr *)&peer, &len);
            // 未来通信就使用sock，后续为文件操作
            if (sock < 0)
            {
                logMessage(ERROR, "accept error  errno : %d",errno);
                exit(2);
            }
            cout << sock << endl;
            logMessage(NORMAL, "accept success");
            //Version 3多线程版
            pthread_t tid;
            ThreadData *data = new ThreadData(this, sock);
            pthread_create(&tid, 0, work, data);
        }
    }

private:
    int _socketfd;
    int _listenfd;
    uint16_t _port;
};
